package com.ibeeking.found.msg.rest.service.impl;


import com.ibeeking.found.common.constants.WxMpConstant;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.msg.rest.service.IWxMpTagsService;
import com.ibeeking.found.msg.rest.service.IOpenService;
import com.ibeeking.found.msg.service.common.dos.WxMpTagsDO;
import com.ibeeking.found.msg.service.common.param.WxMpTagsParam;
import com.ibeeking.found.msg.service.common.query.WxMpTagsPageQuery;
import com.ibeeking.found.msg.service.common.query.WxMpTagsQuery;
import com.ibeeking.found.msg.service.common.vo.WxMpTagsVO;
import com.ibeeking.found.msg.service.mapper.WxMpTagsMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.json.JsonUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.tag.WxUserTag;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @ClassName WxMpTagsServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2020-12-28 09:52
 **/
@Deprecated
@Service
public class WxMpTagsServiceImpl extends ServiceImpl<WxMpTagsMapper, WxMpTagsDO> implements IWxMpTagsService {

    @Resource
    private IOpenService wxOpenServiceImpl;
    @Resource
    private WxMpTagsMapper wxMpTagsMapper;

    @Override
    public List<WxMpTagsVO> list(WxMpTagsQuery wxMpTagsQuery) {
        QueryWrapper<WxMpTagsDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(WxMpTagsDO::getAppId, wxMpTagsQuery.getAppId())
                .like(StringUtils.isNotBlank(wxMpTagsQuery.getTagsName()), WxMpTagsDO::getTitleName, wxMpTagsQuery.getTagsName())
                .eq(WxMpTagsDO::getPublishStatus, PublishStatusEnum.ENABLE.getValue())
                .orderByDesc(WxMpTagsDO::getCreateTime);
        List<WxMpTagsDO> wxMpTagsDOS = wxMpTagsMapper.selectList(queryWrapper);
        return JsonUtils.jsonToList(wxMpTagsDOS, WxMpTagsVO.class);
    }

    @Override
    public Page<WxMpTagsVO> pageList(WxMpTagsPageQuery wxmpTagsPageQuery) {
        QueryWrapper<WxMpTagsDO> queryWrapper = new QueryWrapper<>();
        Page<WxMpTagsDO> page = new Page<>(wxmpTagsPageQuery.getPageNum(), wxmpTagsPageQuery.getPageSize());
        queryWrapper.lambda().like(StringUtils.isNotBlank(wxmpTagsPageQuery.getTagsName()), WxMpTagsDO::getTitleName, wxmpTagsPageQuery.getTagsName())
                .eq(WxMpTagsDO::getAppId, wxmpTagsPageQuery.getAppId())
                .eq(wxmpTagsPageQuery.getPublishStatus() != null, WxMpTagsDO::getPublishStatus, wxmpTagsPageQuery.getPublishStatus())
                .orderByDesc(WxMpTagsDO::getCreateTime);
        page = wxMpTagsMapper.selectPage(page, queryWrapper);
        return BeanUtil.convertPage(page, WxMpTagsVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(WxMpTagsParam wxMpTagsParam) {
        //获取公众号服务
        Long tenantId = UserUtils.getTenantID();
        WxMpService wxMpService = wxOpenServiceImpl.getWxOpenMpService(tenantId);
        try {
            //验证当前公众号标签是否达存储上限
            Optional<List<WxUserTag>> count = Optional.of(wxMpService.getUserTagService().tagGet());
            if (count.isPresent()) {
                if (count.get().size() >= WxMpConstant.WX_MAX_TITLE_COUNT) {
                    throw new BusinessException("当前公众号的标签数量已达到上限100个");
                }
            }
            List<WxUserTag> filter = count.get().stream().filter(node -> wxMpTagsParam.getTagsName().equals(node.getName())).collect(Collectors.toList());
            if (Collections3.isNotEmpty(filter)) {
                throw new BusinessException("当前公众号的标签名称已重复");
            }
            //向微信端请求增加标签
            Optional<WxUserTag> res = Optional.of(wxMpService.getUserTagService().tagCreate(wxMpTagsParam.getTagsName()));
            if (res.isPresent()) {
                WxUserTag tag = res.get();
                wxMpTagsParam.setWxTagsId(tag.getId());
            } else {
                throw new NullPointerException("网络异常");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(e.getMessage());
        }
        //保存数据
        WxMpTagsDO wxMpTagsDO = BeanUtil.convertBean(wxMpTagsParam, WxMpTagsDO.class);
        wxMpTagsDO.setCreateTime(LocalDateTime.now());
        wxMpTagsDO.setModifyTime(LocalDateTime.now());
        return wxMpTagsMapper.insert(wxMpTagsDO) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean modify(WxMpTagsParam wxMpTagsParam) {
        //重名验证
        QueryWrapper<WxMpTagsDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(WxMpTagsDO::getTitleName, wxMpTagsParam.getTagsName())
                .ne(WxMpTagsDO::getId, wxMpTagsParam.getId())
                .eq(WxMpTagsDO::getAppId, wxMpTagsParam.getAppId());
        if (Collections3.isNotEmpty(this.wxMpTagsMapper.selectList(queryWrapper))) {
            throw new BusinessException("当前公众号的标签名称已重复");
        }
        Long tenantId = UserUtils.getTenantID();
        WxMpService wxMpService = wxOpenServiceImpl.getWxOpenMpService(tenantId);
        Optional<List<WxUserTag>> count = null;
        try {
            count = Optional.of(wxMpService.getUserTagService().tagGet());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("网络异常");
        }
        //重名验证
        if (count.isPresent()) {
            List<WxUserTag> tags = count.get();
            if (Collections3.isNotEmpty(tags)) {
                tags = tags.stream().filter(node -> wxMpTagsParam.getTagsName().equals(node.getName())).collect(Collectors.toList());
                if (Collections3.isNotEmpty(tags)) {
                    throw new BusinessException("当前公众号的标签名称已重复");
                }
            }
        }
        boolean rename = false;
        try {
            //更新名称
            rename = wxMpService.getUserTagService().tagUpdate(wxMpTagsParam.getWxTagsId(), wxMpTagsParam.getTagsName());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("网络异常");
        }
        //在本地库中更新名称
        if (rename) {
            WxMpTagsDO wxMpTagsDO = BeanUtil.convertBean(wxMpTagsParam, WxMpTagsDO.class);
            wxMpTagsDO.setModifyTime(LocalDateTime.now());
            return wxMpTagsMapper.updateById(wxMpTagsDO) > 0;
        } else {
            return false;
        }
    }

    @Override
    public WxMpTagsVO view(Long id) {
        WxMpTagsDO wxMpTagsDO = wxMpTagsMapper.selectById(id);
        return BeanUtil.convertBean(wxMpTagsDO, WxMpTagsVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean del(Long id) {
        WxMpTagsDO delete = this.wxMpTagsMapper.selectById(id);
        if (delete == null) {
            throw new BusinessException("标签不存在");
        }
        Long tenantId = UserUtils.getTenantID();
        WxMpService wxMpService = wxOpenServiceImpl.getWxOpenMpService(tenantId);
        //删除
        boolean remove = false;
        try {
            remove = wxMpService.getUserTagService().tagDelete(delete.getWxTitleId());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("网络异常");
        }
        if (remove) {
            return wxMpTagsMapper.deleteById(id) > 0;
        } else {
            return false;
        }


    }

    /***
     * 修改状态
     * @param id
     * @param status
     * @param modifyBy
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean changeStatus(Long id, Integer status, Long modifyBy) {
        WxMpTagsDO wxMpTagsDO = new WxMpTagsDO();
        wxMpTagsDO.setId(id);
        wxMpTagsDO.setModifyBy(modifyBy);
        wxMpTagsDO.setModifyTime(LocalDateTime.now());
        wxMpTagsDO.setPublishStatus(status);
        return wxMpTagsMapper.updateById(wxMpTagsDO) > 0;
    }
}
